feat(daemon): version handshake, skew warnings, restart-aware serve#182
Merged
Conversation
Follow-ups deferred from #179 (connect-retry grace for daemon restarts): - DaemonHandshake now advertises the client binary version with #[serde(default)] so old daemons/clients still interoperate. The daemon logs a deduped daemon_version_skew event when a client's version differs. - The serve stdio proxy reads the daemon's serverInfo.version from proxied initialize responses (sent by daemons of every version) and warns on stderr when it differs from the client, pointing at the new `tracedecay daemon restart` command. `tracedecay post-update` now warns loudly when an unmanaged daemon keeps serving the previous version. - `tracedecay serve` no longer commits to in-process mode just because the socket file is missing: when an installed service claims the socket, it waits out the daemon-restart window with the same connect grace used for per-request reconnects before falling back.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the three daemon-lifecycle follow-ups deferred from #179 (connect-retry grace for daemon restarts).
1. Version field in
DaemonHandshakeclient_version(the connecting binary'sCARGO_PKG_VERSION) with#[serde(default)]: a new daemon parses old handshakes (missing field → empty, never treated as skew), and old daemons ignore the extra field, so mixed-version pairs keep interoperating.daemon_version_skewevent (with atracedecay daemon restarthint) when a client's version differs, deduped per client version inDaemonEngine— proxy clients reconnect per request, so an undeduped log would flood.2. Stale daemon on non-systemd paths
result.serverInfo.versionfrom proxiedinitializeresponses (daemons of every version send it) and warns on stderr: "daemon is version X but this client is Y — runtracedecay daemon restart".tracedecay daemon restartsubcommand restarts the installed service (reusingrefresh_installed_service); when no service is installed it errors with guidance to restart the manualtracedecay daemon runprocess.tracedecay post-updatenow distinguishes "no daemon at all" from "an unmanaged daemon is running" and warns loudly in the latter case instead of the quiet "skipping daemon restart" line.tracedecay daemon runit would drop the request mid-flight and leave no daemon behind, which is worse than a stale one. Plaintracedecay upgrade(which skips post-update) is covered by the skew warnings rather than by changing upgrade's semantics.3. Serve in-process fallback race
tracedecay servestartup no longer commits to in-process mode just because the socket file is missing. Newshould_proxy_serve_to_daemon: if the socket exists → proxy (unchanged fast path); if it's missing but the installed service unit claims exactly this socket (thetracedecay updaterestart window, where shutdown unlinks the socket before the new daemon rebinds) → probe with the sameconnect_with_restart_graceused for per-request reconnects; otherwise → in-process immediately, so startup stays instant when no daemon was ever installed. A stopped-but-installed service falls back to in-process after the grace instead of hard-failing every request.Test plan
cargo check --all-targets,cargo clippy --all-targets,cargo fmt --check— cleanTRACEDECAY_DATA_DIR=$(mktemp -d) cargo test --lib daemon::— 47 passed, including new tests:client_version_skewonly flags real mismatches (empty/old-client version is not skew)DaemonEnginelogs each skewed client version oncedaemon_version_skew_warningfires only for mismatchedinitializeresponses and names both versions + the restart commandcargo test --test mcp_cli_serve_test— 14 passed, including new end-to-end regression test: serve started with no socket but an installed unit proxies to a sentinel daemon that binds 400ms later (distinguishable from in-process fallback) and surfaces the version-skew warning on stderrcargo test --test tool_daemon_test --test cli_help_test --test update_plugin_test— all passed